import Vue from 'vue'
import Vuex from 'vuex'
import router from '@/router'
// import {sleep} from '@/utils/common'
import {maxRetryTimes, hairList} from '@/config/index'
import api from '@/api/index'
import eventBus from '@/store/eventBus'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    gender: 'male',
    photo: '',
    result: {}, // 用来存储确认页图片缓存
    blockedRequestName: new Set(),
    resultLen: 0,
    actionId: 0,
    requestInterval: 1000,
    faceId: '', // 用来存储上传页给后端上传的图片返回的id
    isResultLoading: false,
    correctFace: true // 用户上传的图片是否为人像
  },
  mutations: {
    SET_GENDER (state, val) {
      state.gender = val
    },
    SET_PHOTO (state, val) {
      state.photo = val
    },
    SET_RESULT (state, {name, src, loading}) {
      state.result[name] = state.result[name] || {}
      if (typeof loading !== 'undefined') {
        state.result[name].loading = loading
      }
      if (typeof src !== 'undefined') {
        state.result[name].src = src
      }
    },
    CLEAR_RESULT (state) {
      state.result = {}
      state.blockedRequestName = new Set()
      state.resultLen = 0
      state.actionId++
    },
    REFRESH_ACTION_ID (state) {
      state.actionId++
    },
    SET_REQUEST_INTERVAL (state, val) {
      state.requestInterval = val
    },
    SET_FACE_ID (state, id) {
      state.faceId = id
    },
    SET_CORRECT_FACE (state, val) {
      state.correctFace = val
    },
    ADD_BLOCK_REQUEST (state, req) {
      state.blockedRequestName.add(req)
    },
    REMOVE_BLOCK_REQUEST (state, req) {
      state.blockedRequestName.delete(req)
    },
    SET_RESULT_LOADING (state, val) {
      state.isResultLoading = val
    }
  },
  actions: {
    setGender ({commit}, val) {
      commit('SET_GENDER', val)
    },
    setPhoto ({commit}, val) {
      commit('SET_PHOTO', val)
    },
    setFaceId ({commit}, val) {
      commit('SET_FACE_ID', val)
    },
    clearResult ({commit}) {
      commit('CLEAR_RESULT')
      commit('REFRESH_ACTION_ID')
    },
    clearFaceId ({commit}) {
      commit('SET_FACE_ID', '')
    },
    setResultLoading ({commit}, val) {
      commit('SET_RESULT_LOADING', val)
    },
    async uploadFace ({commit}, photo) {
      // 由于需要等到点击提交键才会提示用户，但是用户提交后就已经开始上传，提升体验，因此需要先存储下状态，等提交照片时才做判断
      commit('SET_CORRECT_FACE', true)
      await api.uploadFace({
        image: photo
      }).then(res => {
        if (!res.error) {
          commit('SET_FACE_ID', res.merge_id)
        } else {
          commit('SET_CORRECT_FACE', false)
        }
      })
    },
    stopGetMergedFace ({commit}) {
      commit('REFRESH_ACTION_ID')
    },
    async getMergedFace ({commit, state}, id) {
      let faceId = state.faceId
      // 先loading，等加载结束解开
      commit('SET_RESULT', {name: id, loading: true})
      let actionId = state.actionId
      let result = ''
      // 失败之后重试N次，可在config中配置
      for (let i = 0; i < maxRetryTimes; i++) {
        await api.mergeFace({
          mergeId: faceId,
          templateId: id
        }).then(res => {
          if (state.actionId !== actionId) {
            return
          }
          // 存储result，用来后面判断是否跳转到错误页
          result = res.result
          res.result && commit('SET_RESULT', {name: id, src: 'data:image/jpg;base64,' + res.result})
          if (id === hairList[state.gender][0].id) {
            // 增加500ms loading时间，以防止下一页出现白屏的情况
            setTimeout(() => {
              // loading中第一张图片加载完后，进入下一页，这样用户就可以直接看到一张图，第一张图不会loading
              eventBus.$emit('firstPhotoReady')
            }, 500)
          }
        })
        if (result) {
          break
        }
      }
      commit('SET_RESULT', {name: id, loading: false})
      if (!result) {
        router.push({
          name: 'errors',
          query: {
            from: 'upload',
            error: 'network-error'
          }
        })
      }
    }
  },
  getters: {
    gender (state) {
      return state.gender
    },
    photo (state) {
      return state.photo
    },
    result (state) {
      return state.result
    },
    resultLen (state) {
      return state.resultLen
    },
    faceId (state) {
      return state.faceId
    },
    isResultLoading (state) {
      return state.isResultLoading
    },
    correctFace (state) {
      return state.correctFace
    }
  }
})
